<?php

define("DIDWW_API_WSDL_TEST", '');
define("DIDWW_API_WSDL", 'http://api.didww.com/api2/index154.php?wsdl');

class DidwwApi {

    private static $_errorCodes = array(
        "100"    =>    "Access denied",
        "150"    =>    "Server error when validating an API client request",
        "151"    =>    "Array has invalid data",
        "200"    =>    "Server error when processing an API client request",
        "300"    =>    "Type not valid",
        "301"    =>    "Protocol not valid",
        "302"    =>    "Unsupported format for this type",
        "303"    =>    "PSTN prefix not supported",
        "400"    =>    "API Order ID not found or invalid",
        "401"    =>    "API Order ID not in valid status",
        "405"    =>       "Transaction refused",
        "410"    =>    "Transaction out of balance",
        "411"    =>    "Account balance is disabled/suspened/has not enough amount for purchases",
        "430"    =>    "Customer: Prepaid Balance disabled or not exist",
        "500"    =>    "Region(s) not found or invalid",
        "501"    =>    "City not found",
        "505"    =>    "DIDs not available for this region",
        "600"    =>    "DID Number not found or invalid",
        );
    /**
     * @var SoapClient
     */
    private $_client;
    /**
     * @var SoapFault
     */
    private $_errorString;
    private $_errorCode;
    private $_authstr;
    private $_callback;


    function setCallback($callback){
        if (!is_string($callback) && !is_array($callback)) {
            return false;
        }
        if (!is_string($callback) && !is_array($callback)) {
            return false;
        }   

        $this->_callback = $callback;
        return true;
    }

    function getClient()
    {
        return $this->_client;
    }

    function getError()
    {
        if($this->_errorCode){
            return "Error: (code: {$this->_errorCode}, message: {$this->_errorString})";
        }
        return NULL;
    }


    function setCredentials($user,$pass,$test = false)
    {
         $this->_client = new SoapClient($test ? DIDWW_API_WSDL:DIDWW_API_WSDL_TEST);
        $this->_authstr = sha1($user . $pass  .  ($test ? 'sandbox'  :''));
    }

    function __construct($user, $pass, $test  = false) {
       $this->setCredentials($user, $pass,$test);
    }

    function getAvailableMethods(){
        $soapFunctions = $this->_client->__getFunctions();
        for ($i = 0; $i < count($soapFunctions); $i++){
            preg_match("/[\s\S]*?(didww_[\s\S]*?)\([\s\S]*?/", $soapFunctions[$i], $matche);
            $soapFunctions[$i] = $matche[1]; 
        }
        return $soapFunctions;
    }
    private function _handleQuery( $method,$params=array()) {
       $params = array_merge(array('auth_string' => $this->_authstr),$params);
            $timeStart = microtime(true);
       try{

          
            $method='didww_'.$method;


            //time measure

       
            $result = $this->_client->__soapCall($method, $params);
         
          
       }catch(SoapFault $e){
             $this->_errorCode = $e->faultcode;
             $this->_errorString = $e->faultstring;
               
             $result = null;
       }
       catch(Exception $e){
            $this->_errorCode = $e->getCode();
            $this->_errorString = $e->getMessage();

            $result = null;

       }
   $timeFinish = microtime(true);
       // If result contains error field trying to resolve error text by error code
       if(isset($result->error) && $result->error>0){
            $result->error = isset ( self::$_errorCodes[$result->error])? JText::_(self::$_errorCodes[$result->error]):
                    'Unknown error with code : '.$result->error ;
       }


       if($this->_callback){

           call_user_func_array($this->_callback,array(
                "result"=>$result,
                "method"=>$method,
                "params"=>$params,
                "error"=>$this->_errorString,
                "code"=>$this->_errorCode,
                "seconds"=>$timeFinish-$timeStart
           ) );
       }
        return $result;
    }


    function getDetails()
    {
        return $this->_handleQuery('getdidwwapidetails');
    }
    
    function getservicedetails($customer_id = 0, $api_order_id = 0){
        return $this->_handleQuery('getservicedetails', array('customer_id' => $customer_id, 'api_order_id' => $api_order_id));
    }

    function getRegions($iso = 0 , $city_prefix = 0, $last_request_gmt = 0) {
        return $this->_handleQuery(
            'getdidwwregions',
            array(
                'country_iso' => $iso,
                'city_prefix' => $city_prefix,
                'last_request_gmt' => $last_request_gmt
            )
        );
    }

    function getCity($iso , $city_prefix)
    {
        return $this->getRegions($iso, $city_prefix);
    }

    function getCountry($iso)
    {
        return $this->getRegions($iso);
    }


    function getPstnRates($iso= 0,$pstn_prefix= 0)
    {
        return $this->_handleQuery('getdidwwpstnrates',array('country_iso_code'=>$iso,'pstn_prefix'=>$pstn_prefix));
    }
    
    /**
     * Update pstn rates on DIDWW side
     * @param array $rates
     */
    function setPstnRates($rates)
    {        
        return $this->_handleQuery('updatepstnrates',array('rates'=>$rates));
    }


    

    function checkPstnNumber($number)
    {
         return $this->_handleQuery('checkpstnnumber',array('pstn_number'=>$number));
    }



    function  orderautorenew($user_id,$did_number,$period,$order_id)
    {
        return $this->_handleQuery('orderautorenew',
                                    array(    'customer_id' => $user_id,
                                            'did_number'=>$did_number,
                                            
                                            'period'=>$period,
                                            
                                                                                'uniq_hash'=> md5(gmdate("Y-m-d").'.'.$order_id)

                                    ));
    }

    /**
     * 
     * @param string $user_id
     * @param string $iso
     * @param string $city_prefix
     * @param int $period
     * @param array $map_data
     * @param string $prepaid_funds
     */
    function createOrder($user_id, $iso, $city_prefix, $period, $map_data, $prepaid_funds, $order_id, $city_id)
    {
        $map_data = $this->convertMapData($map_data);

        return $this->_handleQuery('ordercreate',
                                    array(    'customer_id' => $user_id,
                                            'country_iso_code'=>$iso,
                                            'city_prefix'=>$city_prefix,
                                            'period'=>$period,
                                            'map_data'=>$map_data,
                                            'prepaid_funds'=>$prepaid_funds,
                                            'uniq_hash'=> md5($order_id),
                                            'city_id'=>$city_id
                                    ));
    }

    /**
     * Will cancel order which in valid status (Completed, Pending)
     * Cancelation will not refunds any money and all services will be removed immediately
     * @param string $user_id
     * @param string $did_number
     */
    function cancelOrder($user_id, $did_number)
    {
        return $this->_handleQuery('ordercancel',
                                    array(    'customer_id' => $user_id,
                                            'did_number' => $did_number
                                    ));
    }    

    function updateMapping($user_id, $did_number, $map_data)
    {
        $map_data = $this->convertMapData($map_data);

        return $this->_handleQuery('updatemapping', array(
                                    'customer_id'=> $user_id,
                                    'did_number' => $did_number,
                                    'map_data' => $map_data
        ));
    }
    
    private function convertMapData($mapData)
    {
        if( //$mapData['map_type'] == 'ITSP' || 
            $mapData['map_type'] == 'CITSP')
            $mapData['map_type'] = 'VOIP';
        
        if ($mapData['map_type'] == 'PSTN')
            $mapData['map_detail'] = str_replace('-','',$mapData['map_detail']);
        
        return $mapData;
    }


    function updatePrepaidBalance($customer_id, $prepaid_funds, $operation_type,$system_id)
    {
       return $this->_handleQuery('updateprepaidbalance',
                array(  'customer_id'=>$customer_id,
                        'prepaid_funds'=>$prepaid_funds,
                        'operation_type'=>$operation_type,
                        'uniq_hash'=> md5($operation_type.'.'.$system_id)
                    )
               
                );

                

    }



    function decreaseBalance($customer_id,$prepaid_funds,$system_id,$entropy = ''){
       
        if($prepaid_funds > 0 ){
            $prepaid_funds = -$prepaid_funds;
        }

         $operation = '2';
         if($entropy){
               $system_id.='_'.(string)$entropy;
         }

        return $this->updatePrepaidBalance($customer_id, $prepaid_funds,$operation ,$system_id);
        
    }

    function increaseBalance($customer_id,$prepaid_funds,$system_id,$entropy = ''){
        
        if($prepaid_funds < 0 ){
            $prepaid_funds = -$prepaid_funds;
        }

         $operation = '1';
         if($entropy){
             $system_id.='_'.(string)$entropy;
         }

        return $this->updatePrepaidBalance($customer_id, $prepaid_funds, $operation, $system_id);

    }


    function getPrepaidBalance($customer_id=0)
    {
        return  $this->_handleQuery('getprepaidbalancelist',array('customer_id'=>$customer_id));
        
    }
    function getCdrLog($customer_id,$last_requested_date='2010-01-01')
    {
          return $this->_handleQuery('getfullcdrlog',
                array(
                    'customer_id'=>$customer_id,
                    'last_requested_date'=>$last_requested_date
                    )
                );
    }

    function getDidwwApiDetails()
    {
        return $this->_handleQuery('getdidwwapidetails');
    }

}
?>